package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced;


import io.netty.channel.Channel;
import io.netty.handler.codec.socksx.v5.DefaultSocks5CommandResponse;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import io.netty.handler.codec.socksx.v5.Socks5CommandRequestDecoder;
import io.netty.handler.codec.socksx.v5.Socks5CommandStatus;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyTransferChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.server.AbstractHandleSocksReportServerProxyClientConnectionSuccessTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.decoder.TransferDecoder;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.framework.lazy.cloud.network.heartbeat.protocol.handler.NettySocks5CommandRequestHandler;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.filter.NettySocksServerProxyClientVisitorFilter;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler.NettySocksServerProxyClientVisitorInboundHandler;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler.NettySocksClientProxyServerRealHandler;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
import org.springframework.stereotype.Component;


@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
@Component
public class ServerHandleSocksReportServerProxyClientConnectionSuccessTypeAdvanced
        extends AbstractHandleSocksReportServerProxyClientConnectionSuccessTypeAdvanced<NettyProxyMsg> {


    /**
     * 处理当前数据
     *
     * @param nettyChannelContext 当前通道
     * @param nettyProxyMsg       通道数据
     * @see NettySocksClientProxyServerRealHandler
     */
    @Override
    public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
        // 打开访客通道获取访问数据
        byte[] visitorId = nettyProxyMsg.getVisitorId();
        byte[] clientId = nettyProxyMsg.getClientId();
        Channel visitorChannel = NettyTransferChannelContext.getVisitor(visitorId);
        // 传输通道
        Channel transferChannel = nettyChannelContext.channel();
        ChannelAttributeKeyUtils.buildNextChannel(transferChannel,visitorChannel);
        ChannelAttributeKeyUtils.buildNextChannel(visitorChannel,transferChannel);
        ChannelAttributeKeyUtils.buildVisitorId(transferChannel,visitorId);
        ChannelAttributeKeyUtils.buildClientId(transferChannel,clientId);

        // 根据传输通道获取代理通道
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(transferChannel);

        Byte socks5AddressTypeByte = ChannelAttributeKeyUtils.getSocks5AddressType(nextChannel);
        Socks5AddressType socks5AddressType = Socks5AddressType.valueOf(socks5AddressTypeByte);
        //添加客户端转发请求到服务端的Handler
        // TODO bug fix
        nextChannel.pipeline().addLast(new TransferDecoder(Integer.MAX_VALUE, 1024 * 1024*10));
        // 请求数据开始上报
        nextChannel.pipeline().addLast(new NettySocksServerProxyClientVisitorInboundHandler());
        DefaultSocks5CommandResponse commandResponse =
                new DefaultSocks5CommandResponse(Socks5CommandStatus.SUCCESS, socks5AddressType);
        nextChannel.writeAndFlush(commandResponse);

        nextChannel.pipeline().addLast(new NettySocksServerProxyClientVisitorFilter());

        nextChannel.pipeline().remove(NettySocks5CommandRequestHandler.class);
        nextChannel.pipeline().remove(Socks5CommandRequestDecoder.class);
    }

}
